#pragma once

#include<iostream>
#include<string>
#include<memory>
#include "Socket.hpp"
#include "Connection.hpp"
#include "Epoller.hpp"
#include "Channel.hpp"

using namespace SocketModule;

class listener:public Connection
{
public:
    listener(int port)
    :_port(port),_listensock(std::make_unique<TcpSocket>())
    {
        _listensock->BuildTcpSocketMethod(_port);
        SetEvents(EPOLLIN | EPOLLET);//基类方法
        SetNonBlock(_listensock->Fd());//Common包含的方法
    }

    ~listener(){}

    void Recver() override
    {
        InetAddr client;
        //为什么要循环读？Listen套接字就绪了，代表只有一个新连接到来吗？
        //因此要一次读完，设计ET模式，并且sockfd设置为的非阻塞
        while(true)
        {
            int sockfd = _listensock->Accept(&client);
            if(sockfd == ACCEPT_ERR)
                break;
            else if(sockfd == ACCEPT_CONTINUE)
                continue;
            else if(sockfd == ACCEPT_DONE)
                break;
            else
            {
                //到这里就已经获得了一个合法的fd了
                std::shared_ptr<Connection> conn = std::make_shared<Channel>(sockfd,client);
                conn->SetEvents(EPOLLIN | EPOLLET);
                if(_handler != nullptr)//该handler方法由listensock交给每一个建立的连接
                    conn->RegisterHandler(_handler);
                GetOwner()->AddConnection(conn);
            }
        }
    }

    void Sender() override
    {}

    void Excepter() override
    {}

    int GetSockfd() override
    {
        return _listensock->Fd();
    }
private:
    std::unique_ptr<Socket> _listensock;
    int _port;
};
